동현의 나불나불
백엔드
배포
docker, AWS, github action을 활용한 배포
github_actions_기초
prometheus_이론
kafka 공부
ch1.kafka 시작하기
언어
자바
java 인터페이스
java다형성
java예외
java추상화
java컬렉션
javaThread
프로젝트
바로그림
django-학습-핵심-정리
elasticsearch-검색과-데이터-파이프라인-정리
활용한 기술
바로그림-프로젝트-설계와-시행착오
회고록
백엔드_통합점검
오늘의 식사
Today I Learned
2026_04_15~2026_04_19
2026_04_15
2026_04_16
2026_04_17
2026_04_20~2026_04_27
2026_04_20
2026_04_21
2026_04_22
2026_04_23
2026_04_24
2026_04_27~2026_05_01
2026_04_27
2026_04_28
2026_04_29
2026_04_30
2026_05_01
2026_05_04~2026_05_08
2026_05_04
2026_05_05
2026_05_06
2026_05_07
2026_05_08
2026_05_11~2026_05_15
2026_05_11
2026_05_12
2026_05_13
2026_05_14
2026_05_15
2026_05_21~2026_05_22
2026_05_21
2026_05_22
2026_05_27~2026_05_30
2026_05_27
2026_06_TIL
2026_06_11
2026_06_15
2026_06_16
2026_06_22
2026_06_25
2026_06_26
2026_06_28
2026_07_TIL
cs
네트워크
네트워킹 하향식 접근
http 프로토콜
데이터베이스
DB_SQL기초
Lock_diffrent
웹
os
chapter1 운영체제 서론
chapter2 운영체제 구조
chapter3 프로세스 관리
Home
Contact
Copyright © 2024 |
Yankos
Home
>
Today I Learned
> 2026_04_27~2026_05_01
Now Loading ...
2026_04_27~2026_05_01
2026-05-01 정리본
Thymeleaf 서론 톰캣과 같은 WAS 레벨은 유저가 직접 제어하기 힘들지만 controller 레벨에서는 문제를 인지하고 그 결과를 tomcat에 전달해도 무방하긴 하다. Dispatcher servlet은 서블렛 클래스이기 때문에 httpServletRequest, httpServletResponse를 받는다. controller에서 httpServletRequest, httpServletResponse에 관한 객체를 주입받아 사용할 수가 있다. thymeleaf를 사용하면 이 템플렛 엔진은 우선적으로 html 파일을 찾게 된다. 이 @Responsebody에 따라 http 요청 본문에 담긴 값들을 자바 객체로 변환시켜, 객체에 저장을 하고 이를 전달하게 된다. Thymeleaf 입문 html를 웹에서 보여주는데 spring과 같은 경우는 템플릿 엔진을 사용하게 된다. 이러한 템플릿 엔진을 통해 자바 객체를 html파일에 동적으로 넣어 보내는 것이 가능하다. 스프링 부트에서는 지금 공식적으로 thymeleaf 를 사용한다. 이는 기존의 jsp를 대다수 대체하게 되었는데 그 이유는 다음과 같다. jsp보다 빠르다 html와 관련이 적은 jsp 문법에 대해 배워서 따로 사용하는 할 필요가 없다. Thymeleaf 적용 <p th:text="${user.name}">기본값</p> 위 문장과 같이 html 태그안에 th: prefix를 추가하여 사용을 하게된다. Thymeleaf 입장에서는 이를 해석해서 렌더링을 하게 된다. <p th:text="${content}"></p> <p th:utext="${content}"></p> text와 utetxt가 있다. text는 문자열을 그대로 출력하고 utext는 ‘<’와 같은 앵글 브라켓이 존재하는 경우 utext를 활용하다면 unescape 상태로 문자를 넣을 수가 있어서 상황에 맞게 활용해주도록 하자. 주의 댓글, 게시판과 같은 웹의 작성란에 앵글 브라켓에 대해 escaping 문자에 대한 처리를 넣어두지 않는다면 XSS 공격에 대한 취약점으로 될 수가 있다. <input type="text" th:value="${user.name}" /> user.name의 값이 input value에 들아가게 된다. <a th:href="@{/users/list}">목록</a> 자동으로 context path 포함 <p th:if="${user != null}">로그인 상태</p> <p th:unless="${user != null}">비로그인 상태</p> if else가 아닌 if, not if의 구조인데 조건을 따로 평가하게 된다. 가독성 때문에 unless를 사용하게 된다. <ul> <li th:each="item : ${items}" th:text="${item}"></li> </ul> java의 for each와 비슷하게 흘러간다. 서블릿과 같은 경우 Attribute라는 작은 주머니를 가진다. Spring에서는 주머니보다는 모델을 사용하게 된다. 이 모델은 인터페이스이고 스프링 구현체에서 넣어준다.template가 모델 인스턴스를 가져가서 읽어드리게 된다. model에 있는 값을 꺼내서 렌더링을 계속 진행하게 된다. getMapping 안에 show 라는 것을 선언하게 되었는데 자료구조가 할당되게 된다. addAttribute가 할당된다. 이 addAttribute로 값이 할당되게 된다. 비슷한 공간을 사용한다고 보면 된다. 참고로 thymeleaf에서 랜더링을 할 때는 Object @GetMapping("/user") public String show(Model model) { model.addAttribute("user", new User()); return "user-form"; } 이 show가 있는 controller 클래스에서 넣은 값은 Thymeleaf 템플릿에서 활용하게 된다. <p th:text="${user.name}">이름</p> Thymeleaf에서 폼을 다루거나 랜더링을 할 때 th:object를 활용한다. 먼저 폼을 다루는 경우 객체단위로 바인딩을 하게된다. <form th:action="@{/user}" th:object="${user}" method="post"> <input type="text" th:field="*{name}" /> <input type="text" th:field="*{age}" /> <button type="submit">전송</button> </form> 특정 객체를 기준으로 데이터를 참조할 때 사용하고 하위 태그가 이 객체를 기본 참조 대상으로 활용하게 된다. 한마디로 th:object는 기준 객체를 설정하고, *{}는 그 객체의 프로퍼티에 직접 접근하기 위한 문법이라고 볼 수가 있다. 프로젝트를 구성하는 웹을 구조적으로 설계하고 각 계층에 맞게 접근하기 위해서는 동적인 url을 작성해줘야 한다. url과 uri를 REST하게 설계를 했다면 식별가능한 path를 부여받는다. 앵커 태그에다가 url을 동적으로 생성할 수 있게 설계하고 반복문 <a th:href="@{/users/{id}(id=${user.id})}">상세보기</a> 아래의 경우 tx:text를 쓸때 중괄호에 Original Text가 대체되는 형식으로 돌아가게 된다. th:text에 파이프 기호를 쓰고 일반텍스트를 쓰고 중괄호롤 넣어 최종적으로 돌아가서 문자열이 대체가 된다. 문자열 + 변수와 함께 사용하고 싶을때 사용한다. <p th:text="|이름: ${user.name}|">Original Text</p> java에서 js로 데이터를 넘기고 사용하는 방법이다. js를 사용할 때 보는것이 alert이다. <script th:inline="javascript"> const username = [[${user.name}]]; alert(username); </script> js는 이를 주석으로 인식하고 thymeleaf는 주석안의 값을 활용하는 것이 가능하다. java에 있는 값을 js에 넣어 보내고 싶다면 주석을 활용하면 된다. 주석에다가 thymeleaf 표현식을 넣어주면 js가 생각하지 않고 넘기게 된다. 그러면 thymeleaf가 주석을 제거하고 받아드린다. <script> const name = /*[[${user.name}]]*/ "default"; </script> 참고 : 템플릿 엔진 설정 yaml spring: thymeleaf: prefix: classpath:/custom/ suffix: .txt 이렇게 간단하게 템플릿엔진의 과정을 바꾸는 것을 몇 안되는 문장으로 가능하다. spring boot의 추상화가 되어있기 때문이다. spring boot에서 template 아래의 index.html을 두면 따로 랜더링을 하지 않아도 실행된다. @RequestParam 붙인 것은 Parameter로 반환된다. 프로젝트 방법론 애자일 소프트웨어의 개발 방식의 하나로 변화에 유연하게 대응하면서, 짧은 주기로 가치를 계속 전달하는 방식이다. 우선 작게 만들고 빠르게 검증하고 계속 개선하는 과정을 반복한다. 다음과 같은 애자일 선언문을 기반으로 한다. «애자일 선언문» 우리는 소프트웨어를 개발하고, 또 다른 사람의 개발을 도와주며 소프트웨어 개발의 더 낳은 방법들을 찾아가고 있다. 이 작업을 통해 우리는 다음을 가치있게 여긴다. 1. 공정과 도구보다 개인과 상호작용을 가치있게 여긴다. 2. 포괄적인 문서보다 작동하는 소프트웨어를 가치있게 여긴다. 3. 계약, 협상 보다 고객과의 협력을 가치있게 여긴다. 4. 계획을 따르기 보다 변화에 대응하기를 가치있게 여긴다. 짧은 주기의 개발 단위(스프린트)를 반복하여 하나의 큰 프로젝트를 완성해 나가는 방식이다. 애자일의 핵심은 피드백과 협력이다. (협력과 피드백을 자주, 빨리) 애자일은 방법론이 아니다. 애자일은 협업과 워크플로우를 바라보는 관점, 문화, 사상이다. 이러한 애자일을 계승하여 나온것이 칸반, 스크럼, WBS등이 있다. 스프린트 애자일 스크럼에서 사용하는 개념으로 짧은 시간 동안 목표 기능을 완성하는 개발 사이클이다. 보통 1~2주 단위로 진행되고 작게 만들고 -> 바로 검증 -> 수정 -> 반복을 반복한다 SprintPlanning 이번 스프린트에서 할 일 결정 Development 실제 개발 진행, 기능 구현 Daily Scrum 어제 한 일, 오늘 할 일, 문제점을 짧게 공유 Sprint Review 결과물 시연 Sprint Retrospective 잘한점, 문제점, 개선 방법을 도출하여 다음 스프린트 반영 제품의 작동하는 부분을 제공하기 위해 중점을 둔다. 유저 스토리 사용자 입장에서 기능을 설명하는 짧은 요구사항 문장이다. 이 기능을 누가, 왜 사용하는가에 집중한다. 단순 기능 설명이 아니라 사용자의 목적까지 포함해서 기술한다. As a [사용자], I want [기능], So that [이유/목적] 사용자 중심으로 사고하게 만들어 쓸모없는 기능을 감소하고 우선순위 명확해지고 협업이 쉬워진다. 참고 : 프로젝트에서 난관에 마주친 부분이 있으면 트러블 슈팅 관련 문서 작성하는 것이 중요 협업을 위한 github 기능 github organization GitHub에서 여러 리포지토리(repository)와 멤버들을 관리하는 공동 작업 공간을 의미한다. 조직 계정은 팀 협업에 최적화된다. 각 멤버는 특정 권한을 갖고 프로젝트에 접근가능하다. 기능 리포지토리 관리: 조직 내에서 여러 프로젝트를 각각의 리포지토리로 관리할 수 있다. 조직 소속 리포지토리는 조직에 속하며, 개인 사용자에 귀속되지 않는다. 팀 관리: 조직 내에서 팀을 만들어 특정 리포지토리나 프로젝트에 대한 권한을 부여할 수 있다. 예를 들어, 개발 팀, QA 팀 등으로 나누어 각 팀에 다른 권한을 설정할 수 있다. 권한 관리: 리포지토리나 팀 단위로 접근 권한을 세밀하게 조정할 수 있다. 특정 사용자에게는 읽기 전용 권한을, 다른 사용자에게는 쓰기 권한을 줄 수 있다. 지속적인 통합(CI/CD) 도구 연동: 조직은 빌드 및 테스트 자동화를 위한 다양한 도구(CI/CD 도구)와 쉽게 연동할 수 있어, 팀 전체의 효율성을 높인다. github project, karban 사용자 또는 조직 수준에서 작업을 효과적으로 계획하고 추적할 수 있도록 GitHub의 이슈 및 끌어오기 요청과 통합되는 조정 가능한 테이블, 보드, 로드맵를 제공한다. 여기에 대한 entity를 뽑고 견적을 낼 줄 알아야한다. 흔히 사용하는 템플릿으로 karban보드가 있는데 backlog, Ready, In Progress, In review, Done, Documents와 같이 과정이 분리가 되어 있다. 각 과정에 맞게 일을 배치하고 이동시켜야 한다. backlog는 개발해야 할 기능 or 제품에서 요구하는 사항 기능 및 우선순위를 기록한다. 여기서 주의해야 하는 점이 In progress에 끝낸 작업이더라도 팀원과의 리뷰를 할 것을 In review로 옮기고 검수를 하여 Done으로 이동시켜야 한다. 이렇게 작업을 해두면 시간이 지난 후에 문제가 발생한 경우 tracing을 하고 작업을 열어봐야 한다. github issue 작업의 버그 수정, 새로 추가해야 할 기능, 개선해야 할 기능 등 모든 것을 관리하는 곳이다. 모든 활동 내역에 대해 이슈를 등록하고 이를 기반으로 작업을 진행한다. issue 문서에는 다음과 같은 정보가 기록된다. assignee : 작업이 할당된 사항 projects :개발의 우선순위를 정하게 된다 size : 작업의 규모를 뜻하게 된다. 작업의 규모에 따라 붙을 사람이 정해져 있기 때문에 M에서 크게 벗어나지 않는다 estimate : 내가 할 수 있는 일이 10이 있다면 어느정도 이 작업에서 소모할 것인지 기록한 것이다. startDate : 시작 일 TargetDate : 끝나는 일 참고 : 코드리뷰 문서도 포트폴리오에 활용할 좋은 자산이 되니까 버리지 말것 협업을 위한 브랜치 관리 및 코드리뷰 최초 브랜치로부터 stage와 dev라는 브랜치가 나오게 되는데 우리가 본격적으로 고객들에게 우리의 서비스를 공개하는 것을 배포라고 한다. 이 배포된 것을 기반으로 제공하는 것을 production이라고 한다. 우리는 repository라는 origin branch를 갖는다. 그리고 개발 전용 브랜치인 dev 브랜치를 만들게 된다. 우리는 push를 dev에 바로하면 안된다. 일단 각자의 브랜치를 합치고 개발서버에 일단 실행을 한다. 스태이지는 프로덕트에 들어가기전에 배포환경이랑 동일한 환경에서 테스트를 거치게 되는데 문제가 있는지 검수를 하게 되고 날짜가 지나면 스테이지랑 합치게 된다. dev 브랜치가 생겼으면 메인 브랜치를 쓰는 것이 아니다. 이제는 dev가 메인 브랜치이다. 또한 브랜치는 폴더라는 것이 없다. 논리를 표현할 때는 상하 관계를 쓰게 된다. 피쳐브랜치와 같은 경우 jira 티켓과 같은 것을 붙이게 된다. m001 작업이라고 하면 dev를 기준으로 브랜치를 만들게 된다. m001-mdh 이런 식으로 본인브랜치에다가 본인 작업을 붙인다. 하루를 정하고 모두가 모여서 pr을 날린다(pull request)에 날린다. dev에 이때 코드리뷰 들어가게 된다. 만약 이때 CI/CD를 걸어두면 실행가능한지에 대한 테스트를 거친다. 만약 테스트를 통과하지 못하게 되면 규격외 코드가 된다. 지금은 ci/cd 스크립트를 배우지 않아 적용을 하지 않는다. 이 경우 합치면 각자 브랜치에서 작업한 모든 브랜치의 히스토리가 다 dev에 들어가게 된다. 이렇게 반영을 하는 것을 버전이 올라간다고 표현할 수가 있다. 이것이 가장 기본체계이다. 작업을 pull request에 올리면 issue처럼 코멘트를 달 수가 있는데 이 경우 건설적으로 다는 것이 좋을 수가 있다. 예를 들어, 그런 방향도 좋지만 이런 문제도 발생할 수 있는데 이걸 이렇게 하면 어떻게 하는게 좋지 않을까요? 이런 식으로 다는 것이 좋다. 또한 만약 코드리뷰를 닫지 말고 새로운 커밋메시지를 푸쉬한다면 밑에 댓글처럼 적히게 되고 바로바로 반영이 된다. 이렇게 계속 채워나갔다가 완료를 받게 된다면 #을 누른다면 작업 브랜치를 걸 수가 있다. 그리고 프로젝트에서 이 코드리뷰에 들어가는 것이 가능하다. layered architectrue 애플리케이션을 역할별로 여러 계층으로 나누는 설계방식을 의미한다. 함께 기능하는 여러 개별 layer로 이루어져 있고 각 layer을 특정 역할 및 관심사 별로 구분을 하고 배치하게 된다. Spring의 경우에는 Controller -> Service -> Repository -> Database 이런식으로 출처 : https://velog.io/@jhp1115/3-tier-Layered-Architecture와-MVC Model은 데이터와 관련된 부분이다. 데이터와 비즈니스 로직을 관리한다. 그렇다면 비즈니스 로직에 맞춰서 데이터를 처리하는 Business(Domain) Layer에 속할 것이다. View는 사용자에게 보여지는 부분이다. 그렇기에 사용자와의 상호작용을 통해서 정보를 표시해주고 정보를 가져오는 Presentation Layer에 속할 것이다. Controller는 사용자의 입력된 Domain을 DTO로 변환하는 등의 처리하고 Model과 View를 이어줘야 하기 때문에 Presentation Layer에 속할 것이다. 장점 관심사의 분리 : 각 개별 구성 요소의 단일 책임을 보장이 가능하다. ( 종속성 저하 ) 개발하기 쉬움 : 구현할 아키텍처 패턴이 확실치 않은 경우 좋은 출발점이 될 수 있다. 테스트가 쉬움 : 모든 Layer가 개별적이라서 단위 테스트로 커버될 수 있고 특정 Layer에 속한 구성요소도 분리되어 있어 개별적 테스트가 가능하다. 격리 : 각 Layer가 다른 Layer와 독립적이어서 변경 사항이 다른 Layer로 영향을 끼치지 않는다. 단점 확장성 : 애플리케이션 복잡도가 증가하고 프로젝트에 더 많은 기능을 추가해야하는 경우 확장하는데 비용이 크다. (모놀리식 구현 경향) 상호 의존성 : 하나의 계층이 데이터 수신을 위해선 상위 Layer에 의존하기에 상호 의존성이 존재한다. 배포 : 특정 Layer에 대한 변경은 전체 시스템을 재배포해야 함을 의미한다. ( 큰 Application의 경우 더 문제가 된다. ) 성능 : 비즈니스 요청을 이행하기 위해 Architecture의 여러 Layer를 거쳐야 하는 비효율성으로 인해 고성능 Appication에 적합하지 않다. (병렬처리가 불가능)
Today I Learned
· 2026-05-01
2026-04-30 정리본
CSS 보충 어제 작성한 CSS이외에도 다양하게 활용가능한 부분이 더 있어서 정리해보겠다. CSS emmet 활용 보충 리스트 표현 <!-- ul>li*5 --> <ul> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> 계층 표현 <!-- div>(nav>ol>li*3)+div --> <div> <nav> <ol> <li></li> <li></li> <li></li> </ol> </nav> <div></div> </div> />를 통해 아래 계층으로 지정해서 작성할 수가 있고 *을 통해 어느부분에 반복을 넣을지 지정할 수가 있다. id표현 <!-- id속성 --> <!--span#font-lg--> <span id="font-lg"></span> id 속성은 #을 두어 id의 이름을 어떻게 할지 지정할 수가 있다. 번호매김 및 리스트 반복 동시에 활용 <!-- ol>li.item$@10*5 --> <ol> <li class="item10"></li> <li class="item11"></li> <li class="item12"></li> <li class="item13"></li> <li class="item14"></li> </ol> href 활용한 번호매김 및 값 삽입 <!-- .controller>ol>li.item*5>a[href='#']{아이템$} --> <div class="controller"> <ol> <li class="item"><a href="#">아이템1</a></li> <li class="item"><a href="#">아이템2</a></li> <li class="item"><a href="#">아이템3</a></li> <li class="item"><a href="#">아이템4</a></li> <li class="item"><a href="#">아이템5</a></li> </ol> </div> 이미지 활용 웹사이트에 이미지 링크만 가져와서 표현하는 방법과 로컬에서 저장한 이미지를 불러오는 방법 2가지가 존재한다. <div> <h2>이미지</h2> <p>HTML페이지에 이미지(그림)을 포함하기 위한 태그</p> <img src="https://images.unsplash.com/photo-1490750967868-88aa4486c946?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Nnx8U3ByaW5nfGVufDB8fDB8fHww" alt="Image"> <hr> <img src="/img/flower.jpg" width="300" height="400" title ="예쁜 꽃 사진입니다."> </div> 오디오는 직접 로컬에서 가져와야만 사용가능하다. 예전에는 autoplay 기능이 되었으나 보안상의 이유로 지금은 사용자의 허락을 맡는 기능이 구현되어야 사용가능하다고 한다. <div> <h2>오디오</h2> <audio src = "audio.mp3" controls></audio> </div> 텍스트 강조 텍스트의 강조, 기울기 등을 하고싶을 때 활용 <div> <p> Strong 태그는 중요한 텍스트를 <strong> 강조</strong> 해 <strong> 굵은 글씨</strong>로 표시합니다. </p> </div> <div> <p> b 태그는 중요한 텍스트를 <b> 강조</b> 해 <b> 굵은 글씨</b>로 표시합니다. </p> </div> <div> <p> i 태그는 텍스트를 <i> 강조</i> 해 <i> Italic</i>로 표시합니다. </p> </div> <div> <p> em 태그는 텍스트를 <em> 강조</em> 해 <em> Italic</em>로 표시합니다. </p> </div> 참고 무료 이미지 불러오는 사이트 개발자들도 저작권에 민감하기 때문에 올바른 레퍼런스를 표시하는 것은 중요하다. 사용하는것이 무료인 사이트들이 있다. 1. lorem picsum lorem_picsum 2. unsplash unsplash 참고로 더미 텍스트를 제공해주는 lorem ipsum도 있다. lorem_ipsum CSS flex, grid 사용한 배치 웹페이지에 내용을 담아야 하고 이를 위한 시각화를 할 때 가장 좋은 것은 격자를 활용하는 것이다. 흔히 사용하는 네이버, 구글과 같은 웹사이트들도 가상의 격자를 두어 배치를 한다. 그리고 간격을 통해 내용의 구분을 하기도 한다. 몇몇 유명 사이트들은 여러 메뉴를 topbar를 통해 표기하고 스크롤을 통해 내용을 보여주도록 설계하는 경우가 많다. 이러한 구조에서 많이 사용하는 것이 Flex와 Grid이다. 이를 위해 flex나 grid가 필요한데 컨텐츠를 가운데로 밀거나 스프레드를 시켜야 한다. 또한 전체 레이아웃을 잡을 때 그리드가 들어가고 하나의 줄을 flex로 둔다. CSS flex 플렉스는 가능한 하나의 상자에 구현한다. 이는 1차원에 진행을 하게되고 플렉스가 구현되는 공간을 flex box, 여기있는 요소를 item이라고 한다. 그리고 주축과 교차축을 두어 활용하게 된다. flex를 사용하게 되면 반응형 웹에서 자신의 자리를 최대한 지키면서 객체의 크기가 화면에 맞게 적절히 늘어났다가 줄어드는 것이 가능하기 때문이다. <style> .container{ display: flex; /* flex-direction: column; */ /* 주축 */ justify-content: center; align-items: baseline; } </style> <style> .container { display: flex; justify-content: center; border: .3px dashed gray; } .flex-grow-1 { flex-grow: 1; } .flex-grow-2 { flex-grow: 2; } .flex-basis { flex-basis: 300px; } </style> <body> <!-- .container>.box#item_$*5 --> <div class="container"> <!-- <div class="box" id="item_1"></div> --> <div class="box flex-basis" id="item_1"></div> <!-- <div class="box" id="item_2"></div> --> <div class="box flex-grow-1" id="item_2"></div> <!-- <div class="box" id="item_3"></div> --> <div class="box flex-grow-2" id="item_3"></div> </div> </body> 이렇게 코드가 있다고 하면 justify-content : 남는 공간을 어떻게 배치할 것인지 정한다. flex-basis : flex box안에서의 시작크기를 설정하는 것이다. flex-grow : 컨테이너에 남는 공간이 있다면 그 공간을 가져가는 비율을 정한다. 참고: 폰트를 따로 설정하지 않으면 기본내장 폰트 16px이 된다. 이를 고려하여 보이는 화면을 구성해보도록 하자. CSS grid flex가 1차원을 제어한다면 grid는 행 + 열을 사용하여 2차원을 제어하는 것이 가능하다. 또한 grid-area를 통해 코드 가독성을 높였고 fr을 사용하여 화면의 크기에 따라 자동 배치하는 것이 좋다. grid-template-columns로 컬럼기준으로 크기와 개수를 정한다. repeat(인수,크기) 크기를 인수만큼 반복한다. fr단위 : fraction의 약자로 사용가능한 공간의 비율을 나타낸다. grid-auto-rows: 명시적으로 지정하지 않은 자동생성 행의 높이를 지정 .container{ display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 200px; gap: 10px; } 지정된 그리드 영역이름(grid-area)를 참조하여 그리드 템플릿을 생성한다. .container{ display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 200px; gap: 10px; grid-template-areas: 'tea1 tea1 tea1' 'tree tree tea2' 'tree tree tea2' 'tea3 tea3 tea4' 'tea5 tea5 tea4' ; } .img{ width: 100%; height: 100%; object-fit: cover; } .tree{ grid-area: tree; } .tea1{ grid-area: tea1; } .tea2{ grid-area: tea2; } .tea3{ grid-area: tea4; } .tea4{ grid-area: tea4; } .tea5{ grid-area: tea5; } 지정된 그리드 영역이름(grid-area)를 참조하여 그리드 템플릿을 생성한다. 이를 응용하여 각 html헤더에 맞게 원하는 격자의 설정을 배정하여 만들 수가 있다. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> body{ width:100%; height: 100vh; margin:0; display: grid; grid-template-columns: 1fr 4fr; grid-template-rows: 100px auto 200px; grid-template-areas: 'header header' 'nav sec' 'footer footer' } header{ grid-area: header; background-color: #b1d5c2; height: 100%; width: 100%; } aside{ grid-area:nav; background-color: #F0EBCB; height: 100%; width: 100%; } section{ grid-area : sec; background-color: #CCE4C3; height: 100%; width : 100%; } footer{ grid-area : footer; background-color: #b1d5c2; height: 100%; width : 100%; } </style> </head> <body> <header></header> <aside></aside> <section></section> <footer></footer> </body> </html> HTML Form 태그 활용 <!-- HTML Form Based GET POST PUT PATCH DELETE --> <form method="get" action="/users/login"> <h2> 로그인 </h2> <label for="username"> 아이디 : </label> <input id="username" type="text" name ="username"> <br> <label for="password"> 비밀번호 : </label> <input id="password" type="password" name ="password" placeholder="비밀번호 입력"> <br> 이메일: <input type="email" name ="email" placeholder="이메일을 잘 입력해주십쇼"> <br> <button type = "reset" style="margin-top:10px"> 제출 </button> </form> 이렇게 로그인 정보를 받는 웹페이지를 만드는 경우 GET을 통해 서버에 request를 보내게 된다. 이 경우 url에 모든 정보가 들어가 있어서 보안에 매우 취약한 요청방식이 될 수밖에 없다. 이를 위해 post를 사용하여 정보를 넘기도록 하자. post로 request를 요청하면 URL이 아닌 body부분에 관련정보를 넣어 보이지 않게 보낼 수가 있다. 그리고 URL 길이 제한이 있어 더 긴 데이터도 보내기 좋다. 또한 POST방식은 데이터의 수정/생성/삭제 등을 담당하여 데이터가 변경되기 때문에 캐싱되지 않아 보안에 더 좋다고 볼 수가 있다. Spring Controller Spring Controller은 사용자의 요청을 처리하는 객체이다. 사용자의 요청이 있는 경우 이는 Dispatcher Servlet이 가장 먼저 받고 URL 경로를 기반으로 어떤 컨트롤러로 보낼지 판단하고 보내게 된다. @Controller은 서블렛의 일종은 아니고 그냥 일반 java객체이다. 요청을 처리받은 Controller는 View객체, ModelAndView, String등을 반환하게 된다. @RequestMapping을 통해 매핑이 된 컨텍스트 메서드에 대해 수행을 하게된다. 참고 - SpringBoot의 모든 패키지는 @SpringBootApplication 하위에 설계가 되어야 한다. 그리고 이 하위 패키지들에 대해 컴포넌트 스캔을 시도하게 된다. 그리고 @Component, @Service, @Controller와 같이 bean으로 등록해놓은 것을 bean객체로 인식한다. - static은 정적파일을 저장하고 templates는 동적 페이지를 저장하게 된다. - Springboot는 에러를 하나의 페이지처럼 처리하는 것이 가능하다.
Today I Learned
· 2026-04-30
2026-04-29 정리본
공부 키워드 반복자 패턴 컬렉션의 내부구조를 노출하지 않고도 요소를 순차적으로 탐색할 수 있게 해주는 디자인 패턴을 의미한다. Iterator 객체 실제로 순회하는 객체 hasNext() : 다음요소 있는지 확인 next() : 다음요소 반환 예시 List<String> list = List.of("A", "B", "C"); Iterator<String> it = list.iterator(); while (it.hasNext()) { System.out.println(it.next()); } https를 쓰는 이유 method = GET requestURI = /c01/03 authType = null Host = localhost:8080 Connection = keep-alive sec-ch-ua = "Google Chrome";v="147", "Not.A/Brand";v="8", "Chromium";v="147" sec-ch-ua-mobile = ?0 sec-ch-ua-platform = "Windows" Upgrade-Insecure-Requests = 1 User-Agent = Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Accept = text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Sec-Fetch-Site = none Sec-Fetch-Mode = navigate Sec-Fetch-User = ?1 Sec-Fetch-Dest = document Accept-Encoding = gzip, deflate, br, zstd Accept-Language = ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7 위는 get메서드를 통해 받아온 http resquest 정보이다. 여기에는 사용한 브라우저, os등 개인정보가 포함되어 있어서 노출되면 취약점의 일부가 될 수 있다. 이러한 정보를 감추기 위해 암호화를 사용하고 확인시 인증서가 필요한 https를 http 대신에 사용하고 있는 것이다. ::연산자 String[] favorites = req.getParameterValues("favorite"); System.out.println("favorites..."); // Arrays.stream(favorites) // .forEach(thing -> System.out.println(thing)); //::을 활용한 출력 Arrays.stream(favorites) .forEach(System.out::println); :: 연산자는 이미 존재하는 메서드를 람다식 대신 참조해서 사용하는 문법을 의미한다. 매개변수를 적지 않아도 되어서 가독성이 높아지는 장점이 있다. 이는 그래서 기존 메서드의 호출이나 추가 로직이 없는 경우에 사용하는 것을 추천한다. 표준입출력 Stream은 데이터 입출력시 모든 데이터를 형태와 관계없이 일관된 흐름으로 전송하는 것이다. 프로그래밍에서의 스트림 종류 파일데이터 : 파일의 시작과 끝의 데이터 스트림 http 송수신 데이터: http 헤더, 바디의 데이터들 키보드 입력 : 사용자가 키보드로 입력하는 숫자 및 문자들 그 중 표준 입출력은 java에서는 흔히 System.in, System.out이라고 표시하는 것으로 사용하고 System.in은 InputStream, System.out은 PrintStream에서 담당한다. OS가 기본으로 제공한다. 출력 연산자, 버퍼 표준입출력에서 사용한 System.out.println(), System.out.print()가 java에서 흔히 사용하는 출력연산자이다. 이러한 출력을 통해 데이터를 콘솔, 파일, 등으로 보내게 된다. 하지만 바로 출력을 하게되면 Interrupt에 의한 context switch가 자주 발생하게 되고 이러한 이유로 속도가 느려지게 된다. 이를 위해 데이터를 임시공간에 넣고 한번에 출력하는 쪽으로 방향이 바뀌게 되었다. 이때의 임시공간을 버퍼라고 하고 조건이 되면 한번에 출력하게 된다. 버퍼가 출력하는 경우 줄바꿈 발생 버퍼가 꽉찼을 때 명시적으로 flush()함수를 호춣한 경우 프로그램을 종료하는 경우 EL(Expression Language) JSP 서버사이드에서 자바 코드를 직접 쓰지 않아도 데이터를 꺼내서 간단한 출력이나 연산을 할 수 있게 해주는 연산식 아래는 Jstl.jsp파일에서 일부 가져온 것이다. <p> 보내주신 값은? ${result} </p> jsp파일에 값을 넣기 위해 사용한 java코드이다. req.setAttribute("result", result); EL이 데이터를 찾는 순서 pageScope 현 JSP 페이지 안에서만 사용할 수 있는 영역 requestScope 하나의 http request에서 유지되는 영역, 컨트롤러에서 jsp로 데이터를 넘길때 사용 sessionScope 로그인 정보같은 데이터를 저장할 때 사용 applicationScope 웹 애플리케이션 전체에서 공유되는 영역, 모든 사용자가 같이 접근 가능하다. <% pageContext.setAttribute("name", "page"); request.setAttribute("name", "request"); session.setAttribute("name", "session"); application.setAttribute("name", "application"); %> ${name} 위 코드에서 같은 변수를 여러 스코프를 주고 찾으려고 하면 가장 먼저 발견한 값으로 return을 한다. Jstl JavaServer Pages Tag Library의 약자 JSP에서 자바 코드를 직접 쓰지 않고도 반복, 조건문, 출력, 포맷들을 태그로 처리할 수 있게 하는 라이브러리 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 위 코드를 위에 선언해야지 사용이 가능하다 반복문 사용 <c:forEach var="item" items="${list}"> ${item} </c:forEach> if-else문 사용 <c:choose> <c:when test="${score > 60}">합격</c:when> <c:otherwise>불합격</c:otherwise> </c:choose> EL과 함께 사용되고 java코드를 줄이고 가독성을 향상시키기 위해 사용했다고 볼 수가 있다. DSL Domain Specific Language의 약자로, 특정 분야를 쉽게 표현하기 위해 만든 전용언어를 의미한다. c, java와 같은 프로그래밍 언어는 범용적이라서 비개발자가 이해하기 어렵다. 그래서 특정분야만 쉽게 표현하기 위해 사용한다. 예시 sql : 데이터베이스 특화 html : 웹페이지 구조 특화 css : 스타일 표현 특화 이와 같은 DSL은 “도메인을 얼마나 잘 표현하는가”가 핵심이라고 볼 수가 있다. 랜더링 데이터나 코드로 작성된 내용을 실제 화면에 보이도록 그리는 과정을 의미한다. 대표적으로 서버 사이드 랜더링(SSR), 클라이언트 사이드 랜더링(CSR)이 존재한다. SSR 서버에서 html을 완성해서 보내준다 대표적으로 jsp, thymeleaf가 존재한다. CSR 브라우저에서 JS로 화면을 생성한다. 대표적으로 React가 있다. 초기 로딩은 SSR에 비해 느리지만 이후는 빠르다 Postman으로 패킷받기 실습 postman은 API를 테스트하고 개발할 때 사용하는 대표적인 도구이다. 이것을 통해 아직 배포하지 않고 개발중인 서버에 httpRequest를 보내고 이에 대한 httpResponse를 받아와서 테스트를 진행할 수가 있다. 브라우저에 테스트하는 것은 GET은 쉽지만 POST,PUT, DELETE와 같은 테스트가 어려워서 이 도구를 통해 테스트를 한다고 한다. method = GET requestURI = /c01 authType = null Authorization = Bearer SUPER_SECRET_KEY User-Agent = PostmanRuntime/7.53.0 Accept = */* Postman-Token = 22b1ba7b-5cbe-49bc-84d8-b08caa80b47b Host = localhost:8080 Accept-Encoding = gzip, deflate, br Connection = keep-alive Cookie = Cookie_1=value key= key1value = [val1] key= key2value = [val2] key= key3value = [val3] 쿠키까지 만들어서 테스트를 해본 결과이다. Authorization 관련은 임의의 키를 만들었지만 이후 JWT를 다루면서 생성해볼 것이다. 참고: http를 공부할 때 도움되는 사이트들 **MDN** 파이어폭스를 만든 제단인 모질라에서 웹에 관련된 교육을 운영중인 사이트로 js, http status등 신뢰도 있는 여러정보들을 담고 있다. [MDN 링크](https://developer.mozilla.org/ko/) **w3 school** www를 만든 재단에서 운영하고 있는 사이트이다. 웹과 관련된 여러 교육을 하고 있다. [w3 school 링크](https://www.w3schools.com/) 템플릿 엔진 데이터 + 미리 만들어진 template를 결합하여 html과 같은 결과 문서 등을 만들어주는 도구이다. 위에서 언급한 웹에 대한 랜더링을 시행하는 프로그램이라고 봐도 된다. 서버 사이드 랜더링, SSR JSP 오래된 java기반의 템플릿 엔진 html안에 java코드 삽입하여 사용 EL, JSTL과 함께 사용한다. Thymeleaf HTML 친화적인 템플릿엔진 자연스러운 템플릿 개념 활용 th:와 같은 html 속성을 기반으로 한다. Spring boot에서 표준으로 사용 html Hyper Text Mark Language, 웹페이지를 구조화하기 위해 사용한 언어이다. 웹 브라우저가 사용자에게 정보를 어떻게 표기할 지를 정하는 기능을 수행한다. 문서나 데이터의 현실을 분리 컴퓨터가 쉽게 인식할 수 있도록 구조화 된 표현을 사용 텍스트의 표식을 더하거나 의미를 더하기 위해 사용 hirachy라는 계층적 구조를 가진다. 계층을 가지면 웹 페이지의 구조를 논리를 더해 표현할 수가 있다. 들여쓰기 : indentation, 관행적으로 indent를 부여함으로써 어떤 계층을 갖는지를 시각적으로 표현, 하는 것이 좋다. 같은 계층에 있는 친구를 형제라고 부른다. 위 아래에 있는 계층을 부모라고 부른다. 더 위는 그냥 조상이라고 한다. CSS 선언 실제 css에 있는 스타일을 의미한다. 스타일과 관련된 친구들이 포함된다. 문서중에 어떤 요소를 바꿀 것인지 기록했다면 어떻게 되는지를 보여준다. p { color(속성): blue(속성 값); } 속성: 스타일링을 하려는 대상 속성 값: 속성에서 가질 수 있는 값들을 부여한다. 선택자 *은 전체 선택자를 의미한다. 모든 요소 전부에 { }안에 있는 것을 선택하겠다는 것을 의미한다. p{ } p를 갖는 모든 태그에 적용을 하겠다는 것을 의미 → 태그 선택자 h1 { color: blue; } p { color: blue; } .a{ } . 이 클래스 .뒤는 클래스 이름 special을 클래스로 갖는 모든 것에 대한 선언 h1 { color: blue; } .special { color: blue; } 아이디 선택자 #b{ } #위에 있는 아이디에만 적용을 하겠다는 의미 문서에서 유일하게 식별해야 할때 아이디를 부여하게 된다. 결합자 여러 html 사이의 관계를 적용해서 특정 html에 정밀하게 선택을 하겠다는 것을 의미한다. 자손결합자 div p { color: red; } <div> <p>선택됨</p> <section> <p>이것도 선택됨</p> </section> </div> div안에 있는 모든 p를 선택 자식 결합자 div > p { color: blue; } <div> <p>선택됨</p> <section> <p>선택 안 됨</p> </section> </div> div의 바로 아래 자식인 p만 선택한다. 인접 형제 결합자 h2 + p { color: green; } <h2>제목</h2> <p>선택됨</p> <p>선택 안 됨</p> h2바로 다음에 오는 첫 번째 형제 p만 선택한다. 박스모델 css에서 위치를 어떻게 놓을까라는 것에 대해 어떻게 놓을지 설계를 하는 것이다. html의 모습을 표현하기 위해서 box 모델을 활용하게 된다. box의 위치를 잡아가는 것을 layout이라고 한다. 박스의 동작 인라인 방향으로 연장되어 상위 컨테이너에서 사용가능한 공간을 채운다 새 줄로 행갈이를 한다. 이때 width, height는 존중된다. padding, margin과 같은 요소로 다른 요소들이 밀려난다. Display 브라우저가 박스를 어떻게 보여줄 것인가에 대한 기준을 의미한다 블록 : 박스가 하나의 페이지를 가져가는 것이다. inline : 그 컨텐츠의 다른박스가 남는다면 온 것을 허용한다 inline-block : 공백이 있어도 허용하지 않는 것이다. display : none 태그는 분명 존재하나 시각적으로는 절대 보이지 않는다. Flex 동적으로 layout을 관리할 수 있는 box 하나의 레이아웃 박스가 동적으로 돌아간다. 2개의 축 axis(main, cross)를 가지는 것으로 보이지만 실제로 1차원 위에 돌아가게 된다. 주축과 교차축을 중심으로 박스를 왼,오로 옮기거나 아래로 밀거나 퍼트릴 것인가를 결정하게 된다. 새로운 html 박스를 줄 수 있게 되는데 가장 바깥의 개념을 container이라고 하고 실제로 움직이는 것을 item이라고 한다. 교차축 정렬 : 세로방향 정렬 .container { display: flex; align-items: center; } 줄바꿈 : 아이템이 많으면 자동으로 줄바꿈 .container { display: flex; flex-wrap: wrap; } .container { display: flex; flex-direction: row; /* 방향 */ justify-content: center; /* 가로 정렬 */ align-items: center; /* 세로 정렬 */ flex-wrap: wrap; /* 줄바꿈 */ } Grid 제일 큰 컨테이너 박스를 두고 지역을 나누고 들어가는 방식을 grid라고 한다. 이를 응용한 galary 방식이 쇼핑몰에서 많이 활용된다. .container { display: grid; grid-template-columns: 100px 100px 100px; } flex는 한 줄에서 어떻게 정렬할지에 대해 특화되어 있고 grid는 페이지를 어떻게 나눌지에 대해 특화되어 있어서 실무에서는 Grid를 큰 틀을 정렬하는데 활용하고 Flex를 내부 졍렬하는데 사용한다. CSS에 익숙해지기 위해 하기 좋은 게임들 css diner 쉽게 css를 공부하는 게임 css diner Flexbox Froggy flex를 공부할수 있는 게임 Flexbox Froggy gridGarden Grid Garden css의 내용을 잘 몰라도 활용해도 좋다. Emmet 활용 html을 작성하는데 도움을 주고 특정 키워드만 있으면 긴 html문을 자동 완성시켜준다. 리스트안의 리스트 구현 <!-- div>ul>li^h2+span --> <div> <ul> <li></li> </ul> <h2></h2> <span></span> </div> 반복자를 사용하고 싶을 때 활용하면 좋을 것 같다. <!-- ul>li*5 --> <ul> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> 리스트안의 리스트와 반복문 혼합 사용 <!-- div>(nav>ol>li*3)+div --> <div> <nav> <ol> <li></li> <li></li> <li></li> </ol> </nav> <div></div> </div> 참고 : html 기본양식 자동완성 : !넣고 tab <!DOCTYPE HTML>만 출력하고 싶은 경우 : !!! 넣고 tab
Today I Learned
· 2026-04-29
2026-04-28 정리본
Spring Container(IoC Container) 객체 생성과 생명주기를 개발자가 아닌 Spring이 대신 관리해주는 공간 스프링 컨테이너에 의해 관리되는 재사용 가능한 sw 컴포넌트인 bean을 생성 이를 통해 의존관계 연결, 관리를 수행한다. 스프링 빈들의 생명 주기를 관리하며, 생성된 자바 객체들에게 추가적인 기능을 제공한다. 스프링 컨테이너를 통해 원하는 만큼 많은 객체를 가질 수가 있다. 의존성 주입을 통해 애플리케이션의 컴포넌트를 관리할 수가 있다. @Configuration을 클래스에 붙이면 이 클래스를 설정정보를 사용가능하다. 그리고 클래스 내부에 @Bean을 붙인 메서드를 스프링 컨테이너에 등록하는 것이 가능하다. @Configuration public class AppConfig { @Bean public BeanOne beanOne() { return new BeanOne(beanTwo()); } 의존성 주입(Dependency Injection) 객체가 필요로 하는 다른 객체(의존 객체)를 직접 생성하지 않고, 외부에서 전달받는 설계 방식 public class OrderService { private MemberRepository memberRepository; } 만약 여기서 다른 레포지토리를 사용하고 싶다면 코드를 수정해야 한다. 이러한 강하게 결합된 클래스를 분리하고 애플리케이션의 실행시점에 객체 간의 관계를 결정함으로써 결합도를 낮추고 유연성을 확보한다. 이 경우 외부에서 memberRepository를 넣는 것을 외부에 맡기게 된다. IoC와의 관계 IoC가 조금 더 넓은 개념이라고 볼 수가 있다. IoC를 구현하는 방법이라고 볼 수가 있다. 아래는 DI를 구현한 코드이다. @Service public class OrderService { private final MemberRepository memberRepository; public OrderService(MemberRepository memberRepository) { this.memberRepository = memberRepository; } } 제어의 역전(Inversion Of Controll) 객체 생성과 실행 흐름의 제어권을 개발자에서 프레임워크로 넘기는 것 개발자가 직접 Controller을 호출하지 않고 Spring이 그 역할을 해주는 것을 의미한다. 이 제어의 역전으로 변화하는 요구사항에 대한 확장성을 넓힐 수 있고 코드의 결합도가 낮아져 테스트 용이성을 증가시킬 수가 있다. 이 제어의 역전의 대표적인 예시는 두가지가 있는데 첫번째는 위에서 언급한 의존성 주입이다. 의존성 주입을 통해 두번째로는 스프링 프레임워크가 있다. 우리가 흔히 쓰는 라이브러리의 제어권은 우리한테 있지만 프레임워크의 제어권은 프레임워크가 가진다. 스프링의 경우 객체 메서드의 호출을 스프링에게 맞길 수가 있어 유지 보수성을 키울 수가 있습니다. Servlet 웹요청을 처리하는 클래스이다. http request를 java가 알아듣지를 못한다. 그래서 이것을 java 객체로 변환하는 것이 서블릿이라고 볼 수가 있다. 서블릿은 인터페이스 구조로 되어있다. public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { // 요청 처리 } } httpServletRequest로 클라이언트의 요청정보를 받고 클라이언트에 보낼응답을 HttpServletResponse 형에 저장을 한다. 서블렛의 생명주기 init() 서블릿을 처음 메모리 올릴 때 실행, 서블릿을 초기화하며 처음에 한번만 실행 service() 요청/응답을 처리, 요청이 GET인지 POST인지 구분, doGet, doPost 메소드로 분기 유일하게 여러번 실행되는 단계 destroy() 서블릿 종료요청이 있을때 destroy()메서드로 실행 참고 하나의 객체를 여러 요청이 공유하기 때문에 멀티스레드 문제를 잘 다루는 것이 중요하다 그렇지만 사용자가 직접 서블릿을 다루면 코드가 복잡해져 IoC가 필요하다. 이러한 IoC를 반영한 것이 DispatcherServlet이다. Servlet Container 서블릿을 생성하고 실행하며, http 요청/응답을 관리해주는 서버환경을 의미한다. 대표적인 예시로 Apache Tomcat, Jetty, Undertow가 있는데 Spring boot 환경에서는 Tomcat을 내장하고 있다. 통신하는 순서 클라이언트 요청 발생 Tomcat이 요청 받음 Request/Response 객체 생성 적절한 Servlet 호출 결과를 HTTP 응답으로 변환 클라이언트에게 반환 서블릿 컨테이너는 서버 측에서 동적으로 웹페이지를 생성하기 위해 사용을 하고 서블릿들과 웹서버의 상호작용에서 사용하기 때문에 스프링에서 필수적인 요소라고 보면 된다. WAS(Web Application Server, Servlet Container) 웹 애플리케이션을 실행시키는 서버, 단순 요청에 대한 정적인 파일을 내리는 것뿐만 아닌 비지니스 로직을 처리한다. nginx와 같은 web서버와 같이 사용하기도 하는데 nginx는 정적인 로직에 집중하고 WAS는 동적인 로직에 집중하여 처리를 하게 된다. Servlet Container을 포함하고 있는 실행환경을 의미한다. http요청을 받아 적절한 Servlet으로 전달하고 실행결과를 다시 http응답으로 만들어준다. Template Engine 데이터 + 템플릿을 결합하여 동적인 Html을 만들어주는 기술을 의미한다. Html 틀에 서버에서 가져온 데이터(model)을 넣어서 최종 화면을 생성하는 역할이다. 동적으로 html을 구성할 수 있어서 유용하다. 대표적으로 Tyhmeleaf, JSP등이 있다. model.addAttribute("name", "홍길동"); return "user"; 위와 같은 자바로 값을 전달하고 이를 html 틀에 넣어 결정한다. <h1 th:text="${name}"></h1> <h1>홍길동</h1> Dispatcher Servlet MVC구조의 이 컨트롤러 역할을 하는 핵심 Servlet이다. 모든 http요청을 가장 먼저 받는 진입점이다. 요청을 적절한 Controller로 분배하는 역할을 수행한다. 기존의 Servlet방식은 URL마다 Servlet을 직접 매핑하고 코드가 분산되어서 관리가 어려웠지만 DispatcherServlet의 도입으로 모든 요청을 하나로 모아 공통 로직을 관리하기 쉬워졌다. View Resolver 컨트롤러가 반환한 객체는 논리적 뷰 이름으로 반환받는데 이를 실제 view로 변환해주는 역할을 수행한다. 역할 컨트롤러는 특정 뷰를 식별하기 위해 문자열 형태로 뷰 이름을 반환하게 된다. 뷰 리졸버는 이를 실제 뷰 템플릿 파일로 매핑을 한다. Request Mapping 스프링에서 핵심적인 어노테이션 중에 클라이언트의 HTTP 요청을 특정 컨트롤러 메서드와 연결시켜주는 역할을 수행한다. 쉽게 말하면 URL과 메서드를 매칭시켜주는 역할을 수행한다고 볼 수가 있다. @RestController public class MyController { @RequestMapping("/hello") public String hello() { return "Hello World"; } } Handler Concept Spring에서의 Handler란 클라이언트의 요청을 실제로 처리하는 대상을 의미한다 다른 말로는 URL요청을 받아서 비즈니스 로직으로 실행하는 주최이다. @Controller, @RestController안의 요청처리 메서드이다. Handler를 사용하는 흐름 클라이언트 요청 DispatcherServlet 실행 HandlerMapping → Handler 찾기 HandlerAdapter → 타입과 목적에 맞는 Handler를 찾는다 Controller에서 Handler를 실행하게 된다. ViewResolver → View 반환 리턴 타입 handler로 나오는 return은 view기반, REST기반, 비동기 기반에 따라 나뉘지만 실무 기준으로는 다음과 같다. 웹 페이지 : String + Model REST API : ResponseEntity 간단 API : @ResponseBody + 객체 참고 : 리펙토링이란? 업데이트와 달리 기존 코도와 나오는 결과는 같아야 한다. 동작하는 코드를 더 좋고 가독성 있게 바꾸는 작업이다. 대전제는 동작하는 코드라서 일단 동작부터 시켜야 한다. -> 동작이 일치해야지 리펙토링이다. 참고 : ctrl + o → override한 메서드 부르는 단축키
Today I Learned
· 2026-04-28
2026-04-27 정리본
WEB www(world wide web)을 의미하는 말로 인터넷을 기반으로 하는 하이퍼텍스트 집합을 의미 우리가 생각하는 랜선과 같은 통신망은 이더넷(Ethernet)을 의미한다. www와 하이퍼텍스트 하이퍼텍스트의 하이퍼란? 어떤 단어의 접두사로 사용되었을 때 초월한이라는 의미를 가진다. 하이퍼 텍스트란 단순한 페이지를 초월한 형태의 텍스트라는 것을 의미한다. 하이퍼 링크를 통해 페이지와 페이지를 연결하는 것 이러면 페이지를 넘겨서 문서를 읽는 것이 아닌 연결된 것처럼 페이지를 연결할 수가 있다. 웹에서 공유된 문서는 html로 작성해서 넘겨진다. 팀 버니스리라는 컴퓨터 과학자가 url, html, web까지 같이 무료로 풀어버렸다. html : 웹에서 사용되는 텍스트를 표기하기 위해 사용하는 언어 웹의 핵심은 인터넷이라 불리는 물건 위에서 작동하는 하이퍼텍스트 시스템이다. 이와 비슷하게 MES에서는 웹이랑 비슷 AP라는 것을 API 대신에 사용하게 되고 소켓으로 통신을 하게된다. 웹이 돌아가는 방식 만약 우리가 식당에 입장한다고 하면 우리는 클라이언트가 되고 우리에게 서빙을 해주는 사람은 서버가 된다. 웹도 이와 마찬가지로 정보를 받는 주체는 클라이언트가 된다. 정보를 주는 주체가 되면 서버가 되고 정보를 받는 주체가 되면 클라이언트가 된다. 이는 비동기 통신을 할 때 헷갈릴 수가 있다. RES template, ajax를 다룰 때 다시 생각해야 한다. 웹은 정보공유를 위한 시스템이라고 정해놓았고 웹서버에서 정보를 열람하는 주체는 클라이언트라고 볼 수가있다. 이 정보를 열람하는 sw를 브라우저라고 한다. 웹이라는 곳에서 서버역할을 수행하는 것들 중 대표적인 2가지가 Apache Httpd, Nginx인데 이 두개는 프로세스/스레드기반, 이벤트 기반인 점이 차이가 난다. 이 두개가 웹서버 sw로 애용되고 있다. nginx는 동시처리 강하고 정적파일에 대해 매우 빠른 성능을 가지고 있다. 이들의 경우 80번과 443번 포트를 사용하게 된다. 웹서버는 이미 작성되어 있는 문서 형태(정적인 형태)를 서빙하는 형태로 동작하게 된다. 위 두 포트번호를 위 웹엔진 2개가 사용을 하게 되고 잘 알려져서 이용을 잘 안한다. Q.정적인 컨텐츠만 서빙하면 무슨 문제가 일어날 수 있을까? 우선 네이버와 같은 대부분의 서비스는 클라이언트 요청에 따라 동적으로 제공하고 있다. 이렇게 동작하는 시스템을 웹 애플리케이션이라고 한다. 웹 동적 컨텐츠라고도 한다. 이전의 웹서버는 우리가 사용하기에는 다소 문제가 있다. 이렇게 출시한 것들이 Tomcat, Jetty와 같은 웹 애플리케이션 서버(WAS)이다.웹 애플리케이션은 웹서버 말고 WAS 위에서 돌아가게 된다. 하나의 포트에는 하나의 소프트웨어가 실행된다. 다만 하나의 소프트웨어가 여러 개의 포트번호를 가질 수가있다. 톰캣과 같은 경우 8080번 사용 파이썬과 같은 경우 8000번을 사용 view와 같은 경우 3000번을 사용한다. WAS는 다른 포트를 사용하고 이들을 다른 포트로 받아들이고 전송하는 기능을 수행하는 것 가능하다. 프론트 웹 애플리케이션 react, vue, angular 요즘은 이들을 잘 사용을 안한다. 올해 겨울부터 react는 잘 사용이 안된다. 이제는 next js가 많이 사용된다. js에는 nest.js express가 있다. 백엔드 웹 애플리케이션 django Flask FastAPI → 파이썬 기반의 백엔드 프레임워크 spring -> java java에서는 이제 스프링밖에 쓰이지 않는데 다른 프레임워크들은 스프링이 다 잡아 먹은것이라고 볼 수가 있다. spring의 장점으로는 백엔드 상황에서 주어진 모든 상황을 대응하는 것이 가능하다. 그전에는 jsp을 많이 사용했지만 지금은 thymeleaf로 대체했다고 한다.우리나라뿐만 아니라 다른 여러 회사들도 Spring을 사용한다. 네트워크 우리는 알게 모르게 네트워크라는 것을 사용하고 있다. 네트워크는 주변 장치들을 연결해서 사용하거나 서로 데이터를 공유해서 사용하는 것도 네트워크 연결이라고 볼 수가 있다. LAN(Local Area Network) 여러 컴퓨터가 연결되어서 통신을 할 때 통신 범위에 따라 근거리와 같은 방이나 특정지역에서 통신하는 것을 LAN이라고 한다. 근거리나 주변 장치를 연결할 때 사용하고 컴퓨터와 준하는 장치와 연결하는 것도 LAN으로 포함된다. LAN은 하나의 지역이라고 생각해도 무방하다. 하나의 허브에 여러 대의 컴퓨터와 연결하는 방식이 있고 이를 STAR형, 성형이라고도 한다. 구현 방식 버스 하나의 공통케이블(백본)에 모든 장비 연결 Ring 장비를 원형으로 연결, 한방향으로 데이터 순환 Star 중앙 장비에 모든 장비를 연결, 가장 많이 사용되는 구조 WAN(Wide Area Network) LAN에서 얻은 정보를 기반으로 서로 다른 LAN을 연결시켜 주는 광역 네트워크이다. 대역폭(Brand Width)도 규약을 통해 . 규약이라는 것은 서로 지키도록 협약한 규칙이다. 어떠한 곳에서의 관리를 위해 정해놓은 규칙이다. 컴퓨터와 컴퓨터 사이에 데이터를 주고받는 규약을 프로토콜이라고 한다. OSI 7계층과 TCP/IP OSI 7계층은 이론적인 네트워크이고 TCP/IP는 이를 기반으로 만들어지고 실제로 사용하는 프로토콜이다. 이렇게 새롭게 탄생된 물건이 여러 보급에 의해 보급된다고 하면 호환성 문제가 생기게 된다. 처음에는 규격이라는 것이 존재하지 않아서 서로간의 데이터 교환에 문제가 생기게 된다. 문제가 컴퓨터뿐만 아니라 네트워크를 위한 장비에서도 문제가 생기게 되었다. LAN을 컴퓨터 사이에 끼운다고 해도 통신이 되지는 않는다. 이를 중개해줄 중간장치가 필요한데 중간장치의 규격이 달라서 잘 되지 않았다고 한다. 이를 규정해주는 단체도 등장했는데 여기에는 ISO가 있다. ISO라는 표준화를 결정하는 기구가 있는데 네트워크에서 표준화의 부재를 해결하기 위해 표준 규격을 만들었다. 이것이 OSI Model이다. 그래서 이것을 OSI 7Layer라고 부른다. OSI(Open System Interconnections)의 약자이다. 대부분의 제조사들이 이를 표준으로 해서 이용해서 모든 제조사들이 통신을 최소한으로 보장할 수 있게 되었다. 다만 OSI 7계층은 이론적인 면이 강해서 실무에서 사용하기 힘들었는데 이를 실무에 맞게 변형한 것이 TCP/IP 이다. 데이터의 전송과정에서 데이터를 보낼때 7 → 1으로 내려가고 수신자는 1→ 7로 올라가게 된다. 어떤 곳에 문제가 생겼는데 고치면 주먹구구식 방식인데 이렇게 계층을 나누어 놓으면 어떤 문제가 생겼는지 알기 쉬워진다.특정 계층을 변경해도 다른 계층에 영향을 크게 주지 않는다 이로 인해 네트워크 계층에 모듈화된 개발이 가능하게 되었다. 물리 계층 전기신호가 있는데 전기가 일정한 패턴으로 나오는 것 아날로그 신호랑 디지털 신호로 구분이 된다. 이 중 디지털 신호의 0,1을 비트라는 개념으로 사용하고 있다. 신호가 들어옴 → 1, 신호가 나감 → 0 즉, 실제 우리 눈에는 페이지가 보이는데 0과 1로 구분되는 페이지로 보이게 된다. 컴퓨터로 데이터를 송수신 할 때 컴퓨터 어디서 변환이 되는 것일까? LAN 카드 → 전기신호로 받아드리고 컴퓨터가 보내는 것을 전기신호로 변환할 수 있도록 한다. 이 랜 포트에 무언가를 연결해야 통신이 된다. 전기신호를 주고받는 매개체, 케이블은 컴퓨터, 라우터 간의 신호를 전달하는 매게체가 된다. 구리선, 광섬유가 전기신호가 오가는 길이 된다. UTP 케이블을 잘라보면 선 안이 많이 비어있고 구리선이 배배 꼬아놓아져 있는데 이는 다른 전기신호의 간섭을 낮추기 위해 설계한 것이다. Hub 전기신호는 잘가다가 어느순간 약해지는 데 우리는 어떻게 통신이 이루어지고 있을까? 아날로그 신호를 디지털 신호로 바꾸어주는 행위 → 정형이라고 한다. 허브는 들어온 전기신호를 정확히 똑같이 분배를 해준다. 입력된 하나의 신호를 복제해서 분배하거나 네트워트를 확장할 수 있는 장치이다. 신호가 약해지면 증폭해서 전달해야 하는 역할 수행한다. 데이터링크 계층 물리적으로 연결된 장치 간 ‘신뢰성 있는 데이터 전달’을 담당하는 계층이다. 이때 사용되는 주소가 MAC주소이다. 데이터를 수신받는 장치가 수신과 동시에 송신을 하게 되면 두개 이상의 장치가 송신을 하게 된다면 신호가 충돌 할 수가 있다. 데이터 링크 계층에서는 이러한 오류를 찾고 수정을 해준다. 데이터의 원활한 흐름을 위해 관리를 해준다. 이 데이터링크 계층을 실제로 구현한 표준 기술이 이더넷이다. 이더넷은 LAN에서 데이터를 보내는 실제 규칙이라고 보면 된다. 프레임구조, MAC주소 사용방식, 데이터 전송방식 등 다양한 것을 정의한다. 다수의 컴퓨터, 허브, 스위치를 하나의 네트워크 계층에 보관한다, 네트워크 계층에서 이 이더넷을 사용하고 있다라고 보면 된다. 이더넷은 일반적인 인터넷 방식에서 사용하는 기술 중 하나이다. 만약 장치 A, 장치 B. C,D가 각자의 신호를 보내고 있다고 하면 모든 컴퓨터가 충돌을 발생할 수가 있다. 이더넷에서는 이러한 충돌을 방지하기 위해 프로토콜을 하나 두고 있다. 충돌을 피하기 위해 만들어놓은 프로토콜을 CSMA /CD (Carrier Sense Multiple Access Collision Detection)이 존재한다. 이는 신호 확인 -> 공유 사용 -> 충돌 감지와 같은 3가지 과정을 거쳐 구현된다. 예전에 버스형 이더넷에서 많이 사용되었지만 현재는 스위치 기반의 스타형 구조로 이더넷을 구성하고 있어 많이 사용되지는 않는 것 같다. 2계층의 대표적인 장치으로는 switch가 존재한다. 허브랑 비슷하게 생겼고 어떤 컴퓨터와 연결되면 스위치를 통해 내보내게 된다. 여기서 네트워크를 분배해준다. 스위치는 소규모 네트워크 안에서 서로 연결해서 데이터 공유를 쉽게하는 장치이다. 다만 스위치랑 허브가 결정적인 다른 하나는 입력된 데이터를 일관되게 전송하는 것이 아닌 목적지 하나에만 전달을 한다.는 것이다. 이를 통해 넣어놓은 송신자와 수신자 정보가 있으니 mac주소를 알수있는 hash태그를 통해 거기에만 데이터를 쏴줄수가 있다. MAC주소에 따른 전송이 가능하다는 것은 MAC주소 필터링이 가능하다는 것을 의미한다. MAC주소 IP주소와 동시에 가질 수가 있다. MAC주소는 각각 LAN카드마다 가지는 고유한 번호 전세계에 하나만 존재한다. MAC주소는 총 48bit로 표현을 하게된다. Organization Unique Idenfier → 만든 회사를 표시 Universally Administered Address → 각 요소를 구분해주는 것 IP주소로 접근을 하고자 하고 MAC주소를 모르는 경우 내가 가고싶은 곳의 목적지를 알아야 하니 상대의 MAC주소가 무엇인지 물어보는 과정이자 MAC주소 알려달라고 모든 컴퓨터에게 요청하는 과정을 브로드 캐스트라 한다. 그리고 이 IP주소로 MAC주소를 알아낸 과정을 ARP라고 한다. 그리고 얻은 MAC주소를 이더넷 프레임안에 넣는다. 이더넷 프레임안에 MAC주소가 들어가기 때문에 ARP로 알아낸 MAC주소를 이더넷 헤더에 넣어 전송을 하게 된다. IP로 MAC주소 연결 LAN 환경을 알 수가 있다. WAN 환경은 라우터의 MAC주소를 봐야지 알 수가 있다. 네트워크 계층 서로 다른 네트워크 간에 데이터를 전달하고, 경로를 결정하는 계층이다. IPv4 끝자리 255로 끝나면 IPv4 32비트로 표현 IPv6 ip주소가 고갈난 것에 대비해서 ip주소를 관리하는 것이 필요 A클래스, B클래스 필요하다. IPv4와 다른 방식으로 표현한다. 128bit , 16진수와 같은 값을 포함 라우터 데이터가 어느 경로로 전달하는지 안내할 수 있는 기기이다. 원하는 목적지에 맞는 주소로 최단거리로 안내하는 역할 수행한다. 스위치가 MAC주소 기반으로 동작한다면 라우터는 IP주소를 기반으로 수행한다. 그리고 라우터에는 라우팅과 스위칭이라는 개념이 존재하는데 라우팅 알고리즘으로 최단 거리를 찾아 스위칭을 수행한다. 라우팅: 길을 찾는 것, 최단거리로 진행 스위칭 : 들어온 데이터를 적절한 경로로 빠르게 전달하는 것을 의미한다. 그리고 통신하기 위해서는 다른 라우터를 식별할 줄 알아야한다. IP가 뭘까? 인터넷 프로토콜의 약자, 인터넷 세상에서의 장비 식별을 위한 주체를 의미한다. 라우터를 위한 IP주소는 누가 줄까? → 인터넷 서비스 제공자(Internet Service Provider, ISP)라는 주체가 준다. ISP가 제공하는 망에 연결하여 인터넷을 사용하게 된다. ISP가 제공하는 IP을 공인 IP이라 하고 이 IP를 분해해서 다시 사용하기 때문이다. 사용목적에 따라 구분이 가능한 공인 IP와 사설 IP가 존재한다. 이 주소를 이용해서 전세계의 컴퓨터와 통신을 하게된다. 그리고 주기적으로 바뀌는 공인 IP를 유동 IP라고도 한다. 사설 IP는 내부 IP를 사용하고 인터넷에서 직접 접근이 불가하다. LAN에서 사용하는 IP주소라고 볼 수가 있다. 이러한 사설 IP주소를 쓰는 이유는 IP부족을 어느정도 해결함과 동시에 보안을 위해 사용한다. 외부에서는 하나의 공인IP만 보이게 된다. 10.0.0.0 ~ 10.255.255.255 172.16.0.0 ~ 172.31.255.255 192.168.0.0 ~ 192.168.255.255 → 내부 IP의 예시들이다. 만들 때 제외하고 사용할 수 있도록 하는 것이 좋다. IPv4방식을 차용했고, 4개의 10진수 숫자가 컬럼으로 분배되어 있는 경우를 의미한다. 192.168.15.2 이론적으로 사용할 수 있는 IP의 범위는 0~255가 된다. 마지막에 해당하는 비트는 0이나 255는 절대 사용할 수가 없다. 0이랑 255는 예약되어 있어서 사용할 수가 없다. 전송 계층 tcp 3way handshaking은 데이터를 정확하게 전달하는 것을 목표로 하고 있다. 먼저 상대가 수신가능한 상태인지 확인하고 그 확인이 되면 보내게 된다. ACK는 임의의 숫자를 더해서 보낸다. 다시 송신자 측에서 그 ACK값을 뺀 상태로 SYN을 보내게 된다. 이 과정이 되면 양쪽 모두 데이터를 통신할 준비가 되었다는 것을 의미하고 통신을 시작하게 된다. 포트 프로그램에는 포트번호란 것이 있는데 하나의 컴퓨터안에서 어떤 프로그램에게 데이터를 전달하는 기능을 수행한다. 하나의 프로그램은 여러 포트번호를 가지고 있지만 여러 프로그램은 하나의 포트번호를 가지는 것은 불가능 0~1023까지는 거의 다 예약이 되어있는 포트번호 1024~49151까지는 사전등록 포트. 어떤 프로그램을 쓸 수있어라고 되어있는 포트 49152~65535는 자유롭게 사용가능한 포트 잘 알려진 포트 ssh 22번 네트워크를 통해 다른 컴퓨터에 안전하게 접속하기 위해 사용하는 포트 22번이 너무 잘알려져 있어서 요즘은 다른 포트로 지정해준다고 한다. 그대신 암호화가 된 SFTP(secure FTP)를 22번으로 사용하는데 파일 보낼때는 주로 이 22번을 사용하게 된다. SMTP 25번 : secure이 붙어서 이 포트로 메일을 보내게 된다. http 80번 : 패킷 감청이 되어서 잘 쓰지는 않는다, 그렇지만 보편적으로 알려진 포트번호 https 443번 : 패킷 감청이 불가능, ssl. ttl 인증서로 보안을 해서 전달한다 http 웹에서 데이터를 주고받기 위한 약속 무상태 http 는 통신을 기억하지 않고 상태를 기억하지 않는다. 서버는 이전 요청에 대해 기억하지 않고 매번 새로운 요청으로 처리하게 된다. 비연결성 한번 3way handshake를 하고 나면 종료를 하게 되는데 이후에는 다시 3way handshake를 하게 된다. 병목현상을 줄이고 자원낭비를 줄이기 위해서 사용한다. 하지만 지속적인 연결을 해야할 때는 불편할 수가 있다. 세션과 쿠키 Http은 Stateless한 특성을 가지고 있지만 오랜 연결이나 자주 시도하는 연결에서 서버는 클라이언트가 누구인지 계속 확인을 해야한다. 이 경우 서비스를 안정적이고 빠르게 제공하기 위해 사용을 한다. 쿠키 브라우저에 저장되는 작은 데이터 클라이언트의 상태 정보를 로컬에 저장했다가 참조 하나의 쿠키값은 약 4KB까지 저장이 가능하다 http의 reponse-header에 set-cookie 속성을 사용해 클라이언트에 쿠키를 만든다 브라우저 종료해도 만료시점까지 유지 세션보다 작은 정보를 포함한다. 보안은 상대적으로 약하지만 서버에 부담은 적다. 동작 방식 클라이언트가 페이지를 요청 서버에서 쿠키를 생성 HTTP 헤더에 쿠키를 포함 시켜 응답 브라우저가 종료되어도 쿠키 만료 기간이 있다면 클라이언트에서 보관하고 있음 같은 요청을 할 경우 HTTP 헤더에 쿠키를 함께 보냄 서버에서 쿠키를 읽어 이전 상태 정보를 변경 할 필요가 있을 때 쿠키를 업데이트 하여 변경된 쿠키를 HTTP 헤더에 포함시켜 응답 세션 서버가 사용자 정보를 저장하는 방식, 서버에서 저장을 한다. 브라우저가 종료되면 삭제된다. 서버가 허용하는 한 제한이 없다. 세션 ID로 서버가 클라이언트를 구분하고 이에 맞는 서비스 제공 쿠키에 비해 보안은 강하지만 속도는 느리다. 동작방식 클라이언트가 서버에 접속시 세션ID를 받음 클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장하고 가지고 있음 클라이언트는 서버에 요청할 때, 쿠키에서 받은 세션 ID를 같이 서버에 전달해서 요청 서버는 세션 ID를 전달 받아서 별다른 작업없이 세션 ID로 세션에 있는 클라이언트 정보를 가져와서 사용 클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답 http Request HTTP는 Request를 전송하고, Response를 전송받는 형태이며, HTTP Request Message는 Start Line, Headers, Message Body로 이루어져있다. content-type: 요청 본문에 올라가는 형식이 뭔지 설명 header은 요청을 보낼때 추가적으로 정보를 제공하는 영역, 메타데이터가 포함된다. User-agent : 내가 어떤 것을 사용해서 보낸것인지 표기 content_length : 본문의 길이 Header와 Body 사이에는 한 줄의 공백이 있다. REST API REST란? (Representational State Transfer)의 약자로 해당 상태의 상태를 주고받는 모든 것을 의미한다. HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE, PATCH 등)를 통해 해당 자원(URI)에 대한 CRUD Operation을 적용하는 것을 의미한다. 특징 Server-Client(서버-클라이언트 구조) 자원이 있는 쪽이 server, 요청하는 쪽이 client 서버는 API를 제공하고 비즈니스 로직 처리 및 저장을 책임진다. 클라이언트는 사용자 인증, context, 등을 직접 관리하고 책임진다. Stateless(무상태) http가 stateless를 가지니 http를 이용하는 REST도 stateless를 가진다 세션과 쿠키처럼 context에 정보를 넣지 않아 구현은 비교적 단순해진다. 서버는 각각의 요청을 별개의 것으로 인식하고 처리한다. Cacheable(캐시 처리 가능) 웹에서 사용하는 기존 인프라를 활용가능 즉 캐시를 활용하는 것이 가능하다. 마지막 수정된 시간을 기반으로 하는 Last-Modified Tag,리소스의 내용 자체를 기반으로 한 E-tag를 통해 캐싱을 구현한다. 이 기능을 통해 대량의 요청을 효율적으로 처리 가능하다. Layered System(계층화) 클라이언트는 REST API 서버만 호출하게 된다. REST API 서버는 다층 계층으로 구성될 수가 있다. 이는 보안, 로드 밸런싱등을 위해 사용한다고 볼 수가 있다. 클라이언트는 서버와 통신할 때 어느 계층의 서버인지 알 수가 없다. Uniform Interface(인터페이스 일관성) API를 사용해야 하니 일관된 규칙으로 설계되어야 한다. URI로 지정한 Resource에 대한 요청을 통일하고 일관된 Method를 사용하도록 한다. 또한 서버와 클라이언트가 서로의 상태를 모르니 loosely Coupling 형태를 갖는다고도 볼 수가 있다. http Method GET : 서버에 있는 리소스 조회 POST: 서버에 데이터를 전송하여 요청 데이터 처리, 주로 등록에 사용 PUT : 서버의 기존 리소스를 대체(덮어쓰기), 해당 리소스가 없으면 생성 PATCH : 서버의 리소스 일부 변경 (PUT이 전체 변경, PATCH는 일부 변경) DELETE : 서버에 있는 리소스 삭제 http Response version of HTTP은 요청과 달라도 무방하다. 다만, STATUS CODE는 무조건 정확하게 보내줘야 한다. 이 상태를 보고 어떤 것을 해야 하는지 정확한 스탠스를 취해야 할 필요가 있다. 이것을 어기면 버그가 일어나기가 쉽다. 헤더까지 읽고 나면 HTTP문서로 취급을 하게된다. http Status Code 1xx : 프로토콜을 바꾸거나 그런 특수한 경우에만 보임 → 거의 보이지 않는다. 2xx : 제일 많이 쓰는 것, 204, 205 3xx : url을 바꾸어서 보낸경우 4xx: 네잘못, bad request (중요) 클라이언트가 없는 것을 달라한 경우, 뭐를 요청했는데 없는 것 5xx: 내잘못 (중요) 서버 애플리케이션이 잘못한 경우, timeout, bad gateway 요청은 문제없으나 서버 처리에 문제가 생기는 경우 500은 잘못하면 보안 취약점으로 연결될 수 있기 때문에 stack trace가 쌓이게 하는 악용할 수가 있다. 500은 그래도 무조건 안보여주는 것은 안되지만 java 잘못도 가끔 500이 뜰 수가 있다. 개발시 메세지를 적어줄 수가 있다. DB만큼 설계하는 것이 중요하다. 내가 RESTful 하게 설계했는가?, 내가 돌려지고 있는 곳에 정확하게 설계를 했는가? 때에 따라 내가 의도한 코드와 다르게 사용할 수도 있기 때문이다. 이 때문에 서블릿을 알아야 한다. 서블릿은 인터페이스이고 서블릿이 실행되어야 하는 환경이 필요하다. 그 환경이 WAS이고 tomcat과 jetty가 그 종류다. 그 서블릿을 실행시킬 수 있기 때문에 서블릿 컨테이너라고 한다. 서블릿 컨테이너를 초기화하고 나서 스프링을 동작시킨다. Spring 서론 MVC 패턴 model 애플리케이션의 핵심 데이터와 비지니스 로직을 담당 repository와 상호작용, 데이터 처리 및 유효성 검사 담당 독립적으로 작동하고 view나 controller와 직접적으로 통신하지 않는다. view 사용자에게 보여주는 화면, 즉 UI 담당 사용자 입력을 처리하고 적절한 모델기능을 호출 Controller 사용자의 요청에 대한 조정을 수행한다. 모델 함수의 결과를 받아 뷰에 전달 주의사항 - 결합도 최소화를 위해 구성 요소간의 직접적인 참조를 피해야 한다. - 다른 구성 요소와의 의존성을 최소화해야 한다. spring에서 model에 해당하는 annotation은 없다. controller, service, repository에 관한 어노테이션을 제공해준다. 연관되어 있는 것에 대해 서비스를 제공해준다. 필요하다면 view가 끼어들게 된다. jsp나 thymeleaf가 이 기능을 수행한다. 요청에 대한 조정을 controller에서 수행하게 된다. 만약 정답이 되면 model에서 결과를 만들고 view에서 보여주도록 한다.
Today I Learned
· 2026-04-27
<
>
Touch background to close